<?php
declare (strict_types=1);

namespace app\course\logic\live;

use app\admin\logic\system\Config as SystemConfig;
use app\common\exception\LogicException;
use app\course\logic\base\Course;
use app\course\logic\base\CourseSection;
use app\course\logic\live\Live as LiveLogic;
use app\course\model\live\Live as LiveModel;
use app\user\logic\teacher\Teacher;
use app\user\logic\user\Account as User;
use think\facade\Request;

/**
 * 声网接口逻辑层
 */
class LiveAgora extends LiveModel
{
    /**
     * 接口参数
     *
     * @var [type]
     */
    protected $param;

    /**
     * 课时ID值
     *
     * @var [type]
     */
    protected $section_id;

    /**
     * 当前用户ID
     *
     * @var [type]
     */
    protected $user_id;

    /**
     * 当前用户名称
     *
     * @var [type]
     */
    protected $user_name;

    /**
     * 是否是讲师
     *
     * @var [type]
     */
    protected $is_teacher;

    /**
     * 课时数据
     *
     * @var [type]
     */
    protected $section;

    /**
     * 课程数据
     *
     * @var [type]
     */
    protected $course;

    /**
     * 直播课类型
     *
     * @var [type]
     */
    protected $live_type;

    /**
     * 直播限制人数
     *
     * @var [type]
     */
    protected $limit;

    /**
     * 构造方法
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-02
     */
    public function __construct()
    {
        $this->param      = Request::param();
        $this->section_id = intval($this->param['section_id'] ?? 0);
        $this->user_id    = request()->mid ?: 0;
        $this->user_name  = request()->user ? (request()->user->nick_name ?: '') : '';

        if ($this->section_id) {
            // 课时
            $this->section   = app(CourseSection::class)->where('id', $this->section_id)->where('is_last', 1)->findOrFail();
            $this->course_id = $this->section->course_id;
            $this->course    = app(Course::class)->where('id', $this->course_id)->findOrFail();
            $this->live_type = $this->course->course_live_type;
            $this->limit     = $this->course->limit_buy_count;
            $this->limit     = $this->limit != 0 ?: -1;

            // 讲师身份
            $this->is_teacher = app(Teacher::class)->isTeacher(0, true);
            if ($this->is_teacher) {
                $this->is_teacher = app(Teacher::class)->isTeacherCourse($this->course_id, $this->is_teacher);
            }
        }
    }

    /**
     * 获取后台声网配置
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-10-27
     */
    public function getAgoraConfig()
    {
        $config = SystemConfig::get('course.live.config.agora', []);
        if (empty($config)) {
            throw new LogicException('服务暂不可用');
        }

        foreach ($config as &$val) {
            $val = trim($val, ' ');
        }
        unset($val);

        return $config;
    }

    /**
     * 获取后台声网白板配置
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-10-27
     */
    public function getNetlessConfig()
    {
        $config = SystemConfig::get('course.live.config.netless', []);
        if (empty($config)) {
            throw new LogicException('服务暂不可用');
        }

        foreach ($config as &$val) {
            $val = trim($val, ' ');
        }
        unset($val);

        return $config;
    }

    /**
     * 创建声网教室
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-10-27
     */
    public function createRoom()
    {
        $agora = new Agora('room_create');
        $agora->set_path_param([
            'roomUuid' => $this->section_id,
            'userUuid' => $this->user_id
        ]);
        $agora->set_json_param([
            "roomName"   => $this->section->title,
            "roleConfig" => [
                "teacher" => [
                    "limit"      => 1,
                    "verifyType" => 0,
                    "subscribe"  => 1
                ],
                "student" => [
                    "limit"      => $this->limit,
                    "verifyType" => 0,
                    "subscribe"  => 1
                ]
            ],
        ]);

        return $agora->send();
    }

    /**
     * 查询房间配置
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-02
     *
     * @return [type]                      [description]
     */
    public function getRoomConfig()
    {
        $agora = new Agora('get_config');
        $agora->set_path_param([
            'roomUuid' => $this->section_id,
        ]);
        return $agora->send();
    }

    public function roomInfo()
    {
        $config = $this->getAgoraConfig();
        $info   = app(LiveLogic::class)->getRoomUserInfo($this->section_id, $this->user_id);
        return ['config' => $config, 'info' => $info];
    }

    /**
     * 更新房间配置
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-02
     *
     * @return [type]                      [description]
     */
    public function setRoomConfig()
    {
        $agora = new Agora('set_config');

        $agora->set_path_param([
            'roomUuid' => $this->section_id,
        ]);

        $agora->set_json_param([
            "roomName"   => $this->section->title,
            "roleConfig" => [
                "teacher" => [
                    "limit"      => 1,
                    "verifyType" => 0,
                    "subscribe"  => 1
                ],
                "student" => [
                    "limit"      => $this->limit,
                    "verifyType" => 0,
                    "subscribe"  => 1
                ]
            ]
        ]);

        return $agora->send();
    }

    /**
     * 用户进入房间
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-10-29
     *
     * @return [type]                      [description]
     */
    public function entryRoom()
    {
        $agora = new Agora('entry_room');

        $agora->set_path_param([
            'roomUuid' => $this->section_id,
            'userUuid' => $this->user_id
        ]);
        $agora->set_json_param([
            "userName" => $this->user_name,
            "role"     => $this->is_teacher ? "teacher" : "student",
            // "streamUuid"    => "",
            // "publishType"   => 0,
        ]);

        return $agora->send();
    }

    /**
     * 房间用户列表
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-10-29
     *
     * @return [type]                      [description]
     */
    public function roomUsers()
    {
        // 请求数据验证
        // $this->getValidate()->scene('room_users')->failException()->check($this->param);

        $agora = new Agora('room_users');
        $agora->set_path_param([
            'roomUuid' => $this->section_id,
        ]);
        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 更新用户文字聊天禁用状态
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-02
     *
     * @return [type]                      [description]
     */
    public function setUserChatState()
    {
        // 请求数据验证
        // $this->getValidate()->scene('set_user_state')->failException()->check($this->param);

        $user_name = app(User::class)->getUserName();

        $agora = new Agora('set_user_state');
        $agora->set_path_param([
            'roomUuid' => $this->section_id,
            'userUuid' => $this->param['user_id'],
        ]);
        $agora->set_json_param([
            "userName" => $user_name,
            "muteChat" => $this->param['state'],
        ]);
        $agora->add_headers(['token' => $this->param['token']]);
        return $agora->send();
    }

    /**
     * 发送点对点聊天消息
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-02
     *
     * @return [type]                      [description]
     */
    public function sendPeerChat()
    {
        // 请求数据验证
        // $this->getValidate()->scene('chat_peer')->failException()->check($this->param);

        $agora = new Agora('chat_peer');

        $agora->set_path_param([
            'roomUuid'   => $this->section_id,
            'toUserUuid' => $this->param['to_user_id'],
        ]);

        $agora->set_json_param([
            "message" => $this->param['msg'],
            "type"    => 1,
        ]);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 获取指定房间内的所有用户和流列表
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-02
     *
     * @return [type]                      [description]
     */
    public function getUserStreams()
    {
        // 请求数据验证
        // $this->getValidate()->scene('user_streams')->failException()->check($this->param);

        $agora = new Agora('user_streams');

        $agora->set_path_param([
            'roomUuid' => $this->section_id,
        ]);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 设置用户属性
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-03
     *
     * @return [type]                      [description]
     */
    public function setUserProperties()
    {
        // 请求数据验证
        // $this->getValidate()->scene('set_properties')->failException()->check($this->param);

        $key   = $this->param['key'];
        $cause = json_encode($this->param['cause']);
        $key   = $key ? json_decode($key, true) : $key;
        if (!is_array($key) || !count($key)) throw new LogicException("参数错误");

        foreach ($key as $k => $v) {
            $path_param = [
                'roomUuid' => $this->section_id,
                'userUuid' => $this->param['user_id'],
                'key'      => $k,
            ];
            $json_param = [
                'value' => $v,
                'cause' => $cause
            ];
            break;
        }

        $agora = new Agora('set_properties');

        $agora->set_path_param($path_param);

        $agora->set_json_param($path_param);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 踢出用户
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-04
     *
     * @return [type]                      [description]
     */
    public function kickUser()
    {
        // 请求数据验证
        // $this->getValidate()->scene('set_properties')->failException()->check($this->param);

        $agora = new Agora('kick_out');

        $agora->set_path_param([
            'roomUuid' => $this->section_id,
            'userUuid' => $this->param['user_id'],
        ]);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 获取信息通知列表
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-03
     *
     * @return [type]                      [description]
     */
    public function getSequences()
    {
        $agora = new Agora('sequences');

        $agora->set_path_param([
            'roomUuid' => $this->section_id,
        ]);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 更新房间状态
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-03
     *
     * @return [type]                      [description]
     */
    public function setRoomStates()
    {
        // 请求数据验证
        // $this->getValidate()->scene('set_properties')->failException()->check($this->param);

        $agora = new Agora('set_room_state');

        $agora->set_path_param([
            'roomUuid'  => $this->section_id,
            'roomState' => $this->param['state'],
        ]);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 获取指定房间内的所有流列表
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-03
     *
     * @return [type]                      [description]
     */
    public function getStreams()
    {
        // 请求数据验证
        // $this->getValidate()->scene('streams')->failException()->check($this->param);

        $agora = new Agora('streams');

        $agora->set_path_param([
            'roomUuid' => $this->section_id,
        ]);

        // $agora->set_query_param([
        //     'nextId'    => null,
        //     'count'     => 1000,
        // ]);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

    /**
     * 创建流
     * Author 亓官雨树<lucky.max@foxmail.com>
     * Date：   2020-11-03
     *
     * @return [type]                      [description]
     */
    public function createStreams()
    {
        // 请求数据验证
        // $this->getValidate()->scene('create_streams')->failException()->check($this->param);

        $agora = new Agora('create_streams');

        $agora->set_path_param([
            'roomUuid'   => $this->section_id,
            'userUuid'   => $this->user_id,
            'streamUuid' => $this->param['stream_id'],
        ]);

        $agora->set_json_param([
            "streamName"      => $this->param['stream_name'],
            "videoSourceType" => $this->param['video_source_type'],
            "audioSourceType" => $this->param['audio_source_type'],
            "videoState"      => $this->param['video_state'],
            "audioSate"       => $this->param['audio_state'],
        ]);

        $agora->add_headers(['token' => $this->param['token']]);

        return $agora->send();
    }

}
